package grid;

import java.util.ArrayList;

import info.gridworld.grid.AbstractGrid;
import info.gridworld.grid.Location;

public class DoubleBoundedGrid<E> extends AbstractGrid<E> {

	private Object[][] occupantArray;
	private int rowLen;
	private int colLen;
	
	
	public DoubleBoundedGrid() {
		rowLen = 3;
		colLen = 3;
		occupantArray = new Object[3][3];	
	}
	
	@Override
	public E get(Location loc) {
		if(loc.getRow() <0 || loc.getCol() < 0 || 
				loc.getRow() >= rowLen || loc.getCol() >= colLen )
			return null;
        return (E) occupantArray[loc.getRow()][loc.getCol()];
	}

	@Override
	public int getNumCols() {
		return -1;
	}

	@Override
	public int getNumRows() {
		return -1;
	}

	@Override
	public ArrayList<Location> getOccupiedLocations() {
		ArrayList<Location> theLocations = new ArrayList<Location>();

        // Look at all grid locations.
        for (int r = 0; r < rowLen; r++)
        {
            for (int c = 0; c < colLen; c++)
            {
                // If there's an object at this location, put it in the array.
                Location loc = new Location(r, c);
                if (get(loc) != null)
                    theLocations.add(loc);
            }
        }

        return theLocations;
	}

	@Override
	public boolean isValid(Location loc) {
		return ( loc.getRow()>=0 && loc.getCol()>=0 );
	}

	@Override
	public E put(Location loc, E obj) {
		
		Object[][] oldOccupantArray = occupantArray;
		int oldRowLen = rowLen;
		int oldColLen = colLen;
		
		E oldOccupant = get(loc);
		
		
		if(loc.getRow() >= oldRowLen || loc.getCol() >= oldColLen){
			while( loc.getRow() > rowLen-1 || loc.getCol() > colLen-1 ) {
				oldRowLen = rowLen;
				oldColLen = colLen;
				rowLen *= 2;
				colLen *= 2;
			}
			occupantArray = new Object[rowLen][colLen];
			
			for(int i=0; i<oldRowLen; i++) {
				for(int j=0; j<oldColLen; j++) {
					occupantArray[i][j] = oldOccupantArray[i][j];
				}
			}
		}
		occupantArray[loc.getRow()][loc.getCol()] = obj;
		return oldOccupant;
	}

	@Override
	public E remove(Location loc) {        
        // Remove the object from the grid.
        E r = get(loc);
        occupantArray[loc.getRow()][loc.getCol()] = null;
        return r;
	}


}
